package cn.junechiu.check

import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import java.io.IOException
import java.lang.reflect.Field
import java.net.InetAddress
import java.net.Socket
import java.net.UnknownHostException
import java.security.MessageDigest

object CheckUtils {

    //get app sig
    fun getSig(context: Context): List<String> {
        val signatureList: List<String>
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                // New signature
                val sig = context.packageManager.getPackageInfo(
                    context.packageName,
                    PackageManager.GET_SIGNING_CERTIFICATES
                ).signingInfo
                signatureList = if (sig.hasMultipleSigners()) {
                    // Send all with apkContentsSigners
                    sig.apkContentsSigners.map {
                        val digest = MessageDigest.getInstance("SHA")
                        digest.update(it.toByteArray())
                        bytesToHex(digest.digest())
                    }
                } else {
                    // Send one with signingCertificateHistory
                    sig.signingCertificateHistory.map {
                        val digest = MessageDigest.getInstance("SHA")
                        digest.update(it.toByteArray())
                        bytesToHex(digest.digest())
                    }
                }
            } else {
                val sig = context.packageManager.getPackageInfo(
                    context.packageName,
                    PackageManager.GET_SIGNATURES
                ).signatures
                signatureList = sig.map {
                    val digest = MessageDigest.getInstance("SHA")
                    digest.update(it.toByteArray())
                    bytesToHex(digest.digest())
                }
            }
            return signatureList
        } catch (e: Exception) {
            e.printStackTrace()
            return emptyList()
        }
        return emptyList()
    }

    private fun bytesToHex(bytes: ByteArray): String {
        val hexArray = charArrayOf(
            '0',
            '1',
            '2',
            '3',
            '4',
            '5',
            '6',
            '7',
            '8',
            '9',
            'A',
            'B',
            'C',
            'D',
            'E',
            'F'
        )
        val hexChars = CharArray(bytes.size * 2)
        var v: Int
        for (j in bytes.indices) {
            v = bytes[j].toInt() and 0xFF
            hexChars[j * 2] = hexArray[v.ushr(4)]
            hexChars[j * 2 + 1] = hexArray[v and 0x0F]
        }
        return String(hexChars)
    }

    //在需要的地方进行调用
    fun isPortUsing(port: Int): Boolean {
        var flag = true
        try {
            flag = isPortUsing("127.0.0.1", port)
        } catch (e: Exception) {
        }

        return flag
    }

    //在需要的地方进行调用
    @Throws(UnknownHostException::class)
    fun isPortUsing(host: String, port: Int): Boolean {
        var flag = false
        val theAddress = InetAddress.getByName(host)
        try {
            val socket = Socket(theAddress, port)
            flag = true
        } catch (e: IOException) {
        }

        return flag
    }

    //check xposed 在需要的地方进行调用
    fun antiXposedInject() {
        var xpdisableHooks: Field? = null
        try {
            xpdisableHooks = ClassLoader.getSystemClassLoader()
                .loadClass("de.robv.android.xposed.XposedBridge")
                .getDeclaredField("disableHooks")
            xpdisableHooks!!.isAccessible = true
            xpdisableHooks.set(null, java.lang.Boolean.TRUE)
        } catch (e: NoSuchFieldException) {
        } catch (e: ClassNotFoundException) {
        } catch (e: IllegalAccessException) {
            System.exit(1)
        }
    }

    //check app sig  在需要的地方进行调用
    fun loadSig() {
        System.loadLibrary("checksig")
    }
}
